﻿using System;
using System.Collections.Generic;
using System.IO;

namespace MinecraftGPS.Data
{
    class World
    {
        public static World LoadSave(int i)
        {
            var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), String.Format(@".minecraft{1}saves{1}World{0}", i, Path.DirectorySeparatorChar));

            if (!Directory.Exists(path))
                return null;

            return new World(path);
        }

        private readonly string worldPath;

        public World(string path)
        {
            this.worldPath = path;
        }

        public string WorldPath { get { return worldPath; } }

        public PlayerInfo GetPlayerInfo()
        {
            return GetItem<PlayerInfo>(t =>
            {
                var playerTag = t.Child("Data").Child("Player");

                object[] pos = (object[])playerTag.Child("Pos").Value;
                object[] dir = (object[])playerTag.Child("Rotation").Value;

                return new PlayerInfo(
                    new Coordinates((double)pos[0], (double)pos[1], (double)pos[2]),
                    new Direction((float)dir[0], (float)dir[1]));
            });
        }

        private T GetItem<T>(Func<Tag, T> tagConverter)
        {
            var levelPath = Path.Combine(worldPath, "level.dat");

            if (!File.Exists(levelPath))
                return default(T);

            var file = FirstOrDefault(NamedBinaryTagFile.OpenNBTFile(levelPath));

            if (file == null)
                return default(T);

            return tagConverter(file);
        }

        private T FirstOrDefault<T>(IEnumerable<T> source)
        {
            using (var enumer = source.GetEnumerator())
            {
                if (enumer.MoveNext())
                    return enumer.Current;
                else
                    return default(T);
            }
        }
    }
}